import React from 'react';
import ReactDOM from 'react-dom';
//组件的生命周期
//Mounting: 挂载阶段
//Updating: 更新时阶段
//Unmounting: 卸载阶段
//Error Handling: 错误处理

class Child extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            data: "Old State"
        }
        //先做构造
        console.log('constructor--初始化Child数据');
    }

    //组件将要挂载-------挂载1
    componentWillMount() {
        //异步方法可以先跑起来了
        console.log("componentWillMount--Child");
    }

    //render执行--------挂载2

    //组件加载完成-------挂载3
    componentDidMount() {
        //告诉我们App组件挂载成功
        console.log("componentDidMount--Child");
    }

    //将要接收父组件传来的props
    componentWillReceiveProps() {
        console.log("componentWillReceiveProps--Child");
    }

    //子组件是否应该更新-----更新1
    shouldComponentUpdate() {
        console.log("shouldComponentUpdate--Child");
        return true;//这里必须要有返回值，true则执行更新组件，false则阻止更新
    }

    //组件将要更新-----------更新2
    componentWillUpdate() {
        console.log("componentWillUpdate--Child");
    }
    //render----------------更新3
    //组件更新完成-----------更新4
    componentDidUpdate() {
        console.log("componentDidUpdate--Child");
        console.log("父组件state", this.props.fatherState);
        console.log("子组件state", this.state);
    }

    //组件将要销毁
    componentWillUnmount() {
        console.log("componentWillUnmount--Child");
    }

    handleClick() {
        console.log("这里是更新数据")
        console.log()
        this.setState({
            data: "News State"
        })
    }
    render() {
        //把App渲染到页面
        console.log("render--Child");
        return (
            <div>
                <p>创建阶段-（创建App） </p>
                <ol>
                    <li>constructor(包括父 子 孙子...组件)</li>
                    <li>componentWillMount</li>
                    <li>render</li>
                    <li>componentDidMount</li>
                </ol>
                <hr />

                <p>更新阶段-四步曲</p>
                <button onClick={() => { this.handleClick() }}>更新组件</button> <span>{this.state.data}</span>
                <ol>
                    <li>shouldComponentUpdate</li>
                    <li>componentWillUpdate</li>
                    <li>render</li>
                    <li>componentDidUpdate</li>
                </ol>
                <hr />

                <p>更新阶段-五步曲  <small>只多了一步componentWillReceiveProps</small></p>
                <ol>
                    <li>componentWillReceiveProps</li>
                    <li>shouldComponentUpdate</li>
                    <li>componentWillUpdate</li>
                    <li>render</li>
                    <li>componentDidUpdate</li>
                </ol>
                <p>销毁阶段</p>
                <ol>
                    <li>componentWillUnmount</li>
                </ol>
                <p>错误处理阶段</p>
                <ol>
                    <li>componentDidCatch</li>
                </ol>
                <p>组件的属性改变，会触发组件更新，所以执行组件更新的生命周期函数</p>
            </div>
        );
    }
}

class Father extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            data: "Old Props",
            hasChild: true
        }
        console.log('constructor--初始化Father');
    }
    //----------------------------------
    //组件将要挂载-------挂载1
    componentWillMount() {
        //异步方法可以先跑起来了
        console.log("componentWillMount--Father");
    }

    //render执行--------挂载2

    //组件加载完成-------挂载3
    componentDidMount() {
        //告诉我们App组件挂载成功
        console.log("componentDidMount--Father");
    }

    //将要接收父组件传来的props
    componentWillReceiveProps() {
        console.log("componentWillReceiveProps--Father");
    }

    //子组件是否应该更新-----更新1
    shouldComponentUpdate() {
        console.log("shouldComponentUpdate--Father");
        return true;//这里必须要有返回值，true则执行更新组件，false则阻止更新
    }

    //组件将要更新-----------更新2
    componentWillUpdate() {
        console.log("componentWillUpdate--Father");
    }
    //render----------------更新3
    //组件更新完成-----------更新4
    componentDidUpdate() {
        console.log("componentDidUpdate--Father");

    }
    //----------------------------------
    onPropsChange() {
        console.log("这里开始更新Father组件的data为 New Props")
        this.setState({
            data: "New Props"
        })
    }
    render() {
        console.log("render--Father");
        return (
            <div>
                <button onClick={() => { this.onPropsChange() }}>改变props</button><span> {this.state.data}</span><br />
                <button onClick={() => { this.onDestoryChild() }}>隐藏子组件</button><br />
                <button onClick={() => { this.onDisplayChild() }}>显示子组件</button>
                <hr />
                {
                    this.state.hasChild ? <Child fatherState={this.state} /> : null
                }
            </div>
        )
    }
    onDestoryChild() {
        console.log("干掉子组件--Father")
        this.setState({
            hasChild: false
        })
    }
    onDisplayChild() {
        this.setState({
            hasChild: true
        })
    }
}

ReactDOM.render(
    <div>
        <Father />
    </div>,
    document.getElementById('app')
);
